package com.shangsi.controller;

import com.alibaba.csp.sentinel.AsyncEntry;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.shangsi.service.AsyncService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 流量控制演示
 * @author dzd
 * @date 2021-12-13
 */
@RestController
public class SentinelHelloWorldController {


    @RequestMapping("helloWorld")
    public String helloWorld() {
        //使用限流规则HelloWorld
        try (Entry entry = SphU.entry("HelloWorld")) {
            return "sentinel 大家好！" + System.currentTimeMillis();
        } catch (Exception e) {
            System.out.println("降级-------------------------------------");
            e.printStackTrace();
            //降级处理
            return "系统繁忙，请稍后";
        }
    }


    @RequestMapping("helloWorld2")
    public String helloWorld2() {
        //使用限流规则HelloWorld

        if (SphO.entry("HelloWorld2")) {
            try {
                return "sentinel 大家好 helloWorld2！" + System.currentTimeMillis();
            } catch (Exception e) {
                e.printStackTrace();
                return "xxx";
            } finally {
                SphO.exit();
            }
        } else {
            System.out.println("降级 helloWorld2-------------------------------------");
            //降级处理
            return "系统繁忙，请稍后 helloWorld2";
        }
    }

    /**
     * 注解的方式，原理为aop
     * @return Str
     */
    @SentinelResource(value = "HelloWorld3",blockHandler = "blockHandlerForHelloWorld3")
    @RequestMapping("helloWorld3")
    public String helloWorld3() {
        return "sentinel 大家好 helloWorld3！" + System.currentTimeMillis();
    }


    /**
     * 注解限流的时候的降级方法
     * @param blockException blockException
     * @return str
     */
    public String blockHandlerForHelloWorld3(BlockException blockException){
        blockException.printStackTrace();
        return "系统繁忙，请稍后 helloWorld3!";
    }

    @Resource
    AsyncService asyncService;



    @RequestMapping("helloWorld4")
    public String helloWorld4(){

        AsyncEntry asyncEntry=null;
        try {
            asyncEntry = SphU.asyncEntry("HelloWorld4");
            asyncService.doSomethingAsync(asyncEntry);
            System.out.println("helloWorld4-------------------");
        }catch (Exception e){
            e.printStackTrace();
            return "系统繁忙 helloWorld4";
        }finally {
        }
        return  "helloWorld4-------------------";
    }



    /**
     * 定义规则集合
     */
    @PostConstruct
    public void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        //定义限流规则
        FlowRule flowRule = new FlowRule();
        //定义限流资源
        flowRule.setResource("HelloWorld");
        //定义限流规则类型，qps限流
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //定义qps阈值
        flowRule.setCount(1);
        //添加规则集合
        rules.add(flowRule);
        //加载规则集合
        FlowRuleManager.loadRules(rules);
    }
}
